/* Copyright (c) 2015,2016 Lucky Byte, Inc.
 */
package com.lucky_byte.pay.sched;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.ProcessBuilder.Redirect;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.lucky_byte.pay.jar.Runtime;

/**
 * Shell 脚本任务
 */
@DisallowConcurrentExecution
public abstract class SystemJob extends AbstractJob
{
	private static final Logger logger = LogManager.getLogger();

	protected Path executable = null;

	@Override
	public void doJob(File file, List<String> params,
			JobExecutionContext context) throws JobExecutionException {
		if (this.executable == null) {
			logger.error("没有设置执行脚本的程序[executable]，程序错误.");
			return;
		}
		try {
			List<String> commands = new ArrayList<>();
			commands.add(this.executable.toString());
			commands.add(file.getAbsolutePath());
			if (params != null) {
				for (String param : params) {
					commands.add(param.trim());
				}
			}
			ProcessBuilder builder = new ProcessBuilder();
			builder.directory(Runtime.baseFile());
			builder.command(commands);
			builder.redirectErrorStream(true);
			builder.redirectOutput(Redirect.PIPE);

			logger.trace("开始执行[{}]，引擎[{}].", file.getPath(),
					this.getClass().getSimpleName());

			Process process = builder.start();

			InputStream stream = process.getInputStream();
			BufferedReader reader = new BufferedReader(
					new InputStreamReader(stream));
			StringBuilder output = new StringBuilder("脚本输出：\n");
			while (true) {
				String line = reader.readLine();
				if (line == null) {
					break;
				}
				output.append(line).append("\n");
			}
			logger.info(output.toString());
		} catch (IOException e) {
			logger.error("执行[{}]错误[{}].", file.getPath(), e.getMessage());
		}
	}

	/**
	 * 通过系统的 which 或 where 查询一个可执行程序全路径
	 */
	public Path lookForProgram(String program) {
		boolean is_windows =
				System.getProperty("os.name").toLowerCase().contains("windows");
		ProcessBuilder builder =
				new ProcessBuilder(is_windows ? "where" : "which", program);
		try {
			Process proc = builder.start();
			int retcode = proc.waitFor();
			if (retcode == 0) {
				Path path = null;
				try (BufferedReader reader = new BufferedReader(
						new InputStreamReader(proc.getInputStream()))) {
					path = Paths.get(reader.readLine());
				}
				logger.debug("[{}]的全路径为[{}].", program, path);
				return path;
			}
			logger.warn("[PATH]中未找到[{}].", program);
			return null;
		} catch (Exception ex) {
			logger.warn("查询[{}]的全路径错误[{}].", program, ex.getMessage(),
					ex.getClass().getSimpleName());
			return null;
		}
	}

}
